home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-05 / lanutsrc.zip / SYSTEM.C < prev    next >
Text File  |  1991-03-13  |  13KB  |  451 lines

  1. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2. *                         SYSTEM.C
  3. *                                                                            *
  4. *                             AUTHOR:  Jon Marbry                            *
  5. *                                                                            *
  6. *                  HISTORY:                         *
  7. * 1/25/90 JEM  Created                                 *
  8. *                                                                            *
  9. *                             WHAT:                                          *
  10. * SYSTEM allows the user's batch files to access information about the       *
  11. * computer's operating hardware and software                                 *
  12. *                                         *
  13. *                  INPUT:                         *
  14. *                                         *
  15. *                  OUTPUT:                         *
  16. *                                                                            *
  17. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <malloc.h>
  21. #include <string.h>
  22. #include <ctype.h>
  23.  
  24. #include "hardware.h"
  25. #include "lantasti.h"
  26.  
  27. struct token_table {
  28.   char *token;      /* keyword */
  29.   int type;         /* keyword classifier */
  30.   int (*vfn)();     /* function to evaluate for value substitution */
  31.   int value;        /* integer value to return if CONST and no fn. given */
  32. };
  33.  
  34. enum token_class {CPU,FPU,VIDEO,MEM,DISK,EXT,EXP,MOUSE,DOSVER,LANVER,CONST,
  35.                   EQ,NE,LT,GT,LE,GE,AND,OR,RPAR,LPAR,USER,RESULT};
  36.  
  37. char *class_names[] = {"CPU","FPU","VIDEO","MEM","DISK","EXT","EXP","MOUSE",
  38.                         "DOSVER","LANVER","CONST","EQ","NE","LT","GT","LE",
  39.                         "GE","AND","OR","RPAR","LPAR","USER","RESULT"};
  40.  
  41. struct token_table keywords[] = {
  42.   {"CPU",CPU,cpu_type,0},
  43.   {"FPU",FPU,fpu_present,0},
  44.   {"VIDEO",VIDEO,video_type,0},
  45.   {"MEMORY",MEM,ram_free,0},
  46.   {"MEM",MEM,ram_free,0},
  47.   {"DISK",DISK,disk_space,0},
  48.   {"EXPANDED",EXP,ems_avail,0},
  49.   {"EXP",EXP,ems_avail,0},
  50.   {"EXTENDED",EXT,ext_avail,0},
  51.   {"EXT",EXT,ext_avail,0},
  52.   {"MOUSE",MOUSE,mouse_present,0},
  53.   {"DOSVER",DOSVER,get_dos_version,0},
  54.   {"DOS",DOSVER,get_dos_version,0},
  55.   {"LANVER",LANVER,get_lan_version,0},
  56.   {"LAN",LANVER,get_lan_version,0},
  57.   {"=",EQ,NULL,0}, 
  58.   {"EQ",EQ,NULL,0},
  59.   {"==",EQ,NULL,0},
  60.   {"NE",NE,NULL,0},    
  61.   {"!=",NE,NULL,0},    
  62.   {"LT",LT,NULL,0},
  63.   {"GT",GT,NULL,0},
  64.   {"LE",LE,NULL,0},
  65.   {"GE",GE,NULL,0},
  66.   {"AND",AND,NULL,0},
  67.   {"&",AND,NULL,0},
  68.   {"&&",AND,NULL,0},
  69.   {",",AND,NULL,0},
  70.   {"OR",OR,NULL,0},
  71.   {"|",OR,NULL,0},
  72.   {"||",OR,NULL,0},
  73.   {")",RPAR,NULL,0},
  74.   {"(",LPAR,NULL,0},
  75. /* general purpose constants */  
  76.   {"YES",CONST,NULL,TRUE},
  77.   {"NO",CONST,NULL,FALSE},
  78. /* processor types */  
  79.   {"8088",CONST,NULL,88},
  80.   {"8086",CONST,NULL,88},
  81.   {"80286",CONST,NULL,286},
  82.   {"80386",CONST,NULL,386},
  83.   {"80486",CONST,NULL,486},
  84. /* video board types */  
  85.   {"VGA",CONST,NULL,4},
  86.   {"MCGA",CONST,NULL,4},
  87.   {"EGA",CONST,NULL,3},
  88.   {"CGA",CONST,NULL,2},
  89.   {"HERC",CONST,NULL,1},
  90.   {"HERCULES",CONST,NULL,1},
  91.   {"MONO",CONST,NULL,0},
  92.   {"MDA",CONST,NULL,0}
  93.   
  94. };
  95. #define NUM_KEYWORDS sizeof(keywords) / sizeof(struct token_table)
  96.  
  97. /* global token stack info */
  98. #define STACKSIZE 60
  99. int stack[STACKSIZE];
  100. int stack_ptr = STACKSIZE;
  101.  
  102. /* global command line and current token */
  103. #define CMD_LINE_LENGTH 1024
  104. char gl_line[CMD_LINE_LENGTH],gl_token[80];
  105. char *cmdline = gl_line;
  106.  
  107. /* stack_items ********************************************************************
  108. Report the number of items on the stack
  109. *****************************************************************************/
  110. int stack_items() {
  111.   return(STACKSIZE - stack_ptr);
  112. }
  113.  
  114. /* ncompare ********************************************************************
  115.  
  116. *****************************************************************************/
  117. ncompare(loperand,operator,roperand)
  118.   int loperand,operator,roperand;
  119. {
  120.   switch (operator) {
  121.     case EQ:
  122.       return(loperand == roperand);
  123.     case NE:
  124.       return(loperand != roperand);
  125.     case LT:
  126.       return(loperand < roperand);
  127.     case GT:
  128.       return(loperand > roperand);
  129.     case LE:
  130.       return(loperand <= roperand);
  131.     case GE:
  132.       return(loperand >= roperand);
  133.     case AND:
  134.       return(loperand && roperand);
  135.     case OR:
  136.       return(loperand || roperand);
  137.     default:
  138.       puts("Error: Invalid relational operator encountered");
  139.       exit(-1);
  140.       break;
  141.   }  
  142. }
  143.  
  144. /* push ********************************************************************
  145.  
  146. *****************************************************************************/
  147. push(item)
  148.   int item;
  149. {
  150.   if (stack_ptr) 
  151.     stack[--stack_ptr] = item;
  152.   else {
  153.     puts("Parser error (stack overflow)");
  154.     exit(-1);
  155.   }  
  156. }
  157.  
  158. /* pop ********************************************************************
  159.  
  160. *****************************************************************************/
  161. int pop(item)
  162.   int item;
  163. {
  164.   if (stack_ptr < STACKSIZE)
  165.     return(stack[stack_ptr++]);
  166.   else {
  167.     puts("Syntax error: Invalid expression");
  168.     exit(-1);
  169.   }
  170. }
  171.  
  172. /* find ********************************************************************
  173.  Returns index of a token in the keyword table table or -1
  174.  if the token is not in the table
  175. *****************************************************************************/
  176. find(token)
  177.   char *token;
  178. {
  179.   int i;
  180.   
  181.   for (i = 0; i < NUM_KEYWORDS; i++) {
  182.     if (strcmp(keywords[i].token,token) == 0) break;
  183.   }
  184.     
  185.   return((i < NUM_KEYWORDS) ? i : -1);
  186. }  
  187.  
  188. /* get_token ********************************************************************
  189. Gets the next token from a text string. If successful, returns a pointer to
  190. the current position in <string>, NULL otherwise.
  191. *****************************************************************************/
  192. int get_token()
  193. {
  194.   int done,found;
  195.   struct token_table out_token;
  196.   char *token;
  197.  
  198.   done = found = FALSE;
  199.   token = gl_token;
  200.   *token = 0;
  201.    
  202.   while (!done) {
  203.     switch (*cmdline) {
  204.       case '\n':
  205.       case ' ':        /* check for junk characters */
  206.         if (found) done = TRUE;
  207.         break;  
  208.       case '=':         /* check for relational operators */
  209.       case '!':
  210.       case '<':
  211.       case '>':  
  212.       case '&':
  213.       case '|':
  214.         if (found) {    /* if we've got a token, a rel op ends it */
  215.           done = TRUE;
  216.           cmdline--;
  217.           break;
  218.         }
  219.         else {
  220.           *token++ = *cmdline;    /* otherwise, see if it's a two char rel op */
  221.           if ('=' == *(cmdline + 1)) {
  222.             cmdline++;             /* copy the second character */
  223.             *token++ = *cmdline;
  224.           }
  225.           done = found = TRUE;
  226.           break;
  227.         }  
  228.       case '(':        /* parentheses are complete tokens, thank you */
  229.       case ')':
  230.         if (found) {   /* if we've got a token, a paren ends it */
  231.           done = TRUE;
  232.           cmdline--;
  233.           break;
  234.         }
  235.         else {         /* otherwise, just copy the token */
  236.           *token++ = *cmdline;
  237.           done = found = TRUE;
  238.           break;
  239.         }  
  240.       case 0:           /* we've come to the end of the string */
  241.         done = TRUE; found = FALSE;
  242.         break;  
  243.       case '.':
  244.         break;  
  245.       default:
  246.         found = TRUE;
  247.         *token++ = *cmdline;  
  248.         break;
  249.     }
  250.     if (*cmdline != 0) cmdline++;
  251.   }   
  252.   *token = 0;       /* null terminate the token */       
  253.   
  254. }
  255.  
  256. /* is_relop ********************************************************************
  257.  
  258. *****************************************************************************/
  259. is_relop(n)
  260.   int n;
  261. {
  262.   return((n >= EQ) && (n <= OR));
  263. }
  264.  
  265. /* substitute ********************************************************************
  266.  
  267. *****************************************************************************/
  268. int substitute(token,class)
  269.   char *token;
  270.   int class;
  271. {
  272.   if (class < 0) return(atoi(token));
  273.   
  274.   if (is_relop(keywords[class].type)) return(keywords[class].type);
  275.  
  276.   if (keywords[class].vfn != NULL) return((*keywords[class].vfn)());
  277.  
  278.   return(keywords[class].value);
  279. }
  280.  
  281. /* evaluate ********************************************************************
  282.  
  283. *****************************************************************************/
  284. evaluate() {
  285.   int operator,left,right,result;
  286.  
  287.   while (TRUE) {
  288.     if (stack_items() < 3) break;
  289.     right = pop();
  290.     
  291.     operator = pop();
  292.     left = pop();
  293.     
  294.     result = ncompare(left,operator,right);
  295.     
  296.     push(result);
  297.   }
  298. }
  299.  
  300. /* report ********************************************************************
  301. Display current system hardware and software configuration.
  302. *****************************************************************************/
  303. report() {
  304.  
  305. puts("SYSTEM utility for LANtastic -- Copyright 1990 by SoftMagic, Inc.");
  306. puts("All rights reserved.  LANtastic is a trademark of Artisoft, Inc.\n");
  307. puts("Current system configuration:");
  308. puts("───────────────────────────────────");  
  309. puts("Hardware");
  310. printf(   "  CPU: 80%d\n",cpu_type());
  311. if (fpu_present()) puts("  FPU: INSTALLED");
  312. else puts("  FPU: NOT INSTALLED");
  313. printf(   "  Video: ");
  314. switch (video_type()) {
  315.   case 0: /* mono */
  316.     printf("Monochrome\n");
  317.     break;
  318.   case 1: /* herc */
  319.     printf("Hercules\n");
  320.     break;
  321.   case 2:
  322.     printf("CGA\n");
  323.     break;
  324.   case 3:
  325.     printf("EGA\n");
  326.     break;
  327.   case 4:
  328.     printf("MCGA/VGA\n");
  329.     break;
  330. }
  331. if (mouse_present()) puts("  Mouse: INSTALLED");
  332. else puts("  Mouse: NOT INSTALLED");
  333.  
  334. puts("───────────────────────────────────");  
  335. puts("Available Memory");
  336. printf("  Conventional: %dK\n",ram_free());
  337. printf("  Expanded:     %dK\n",ems_avail());
  338. printf("  Extended:     %dK\n",ext_avail());
  339.  
  340. puts("───────────────────────────────────");  
  341. printf("Disk space available: %dK\n",disk_space());
  342.  
  343. puts("───────────────────────────────────");  
  344. puts("Software");
  345. printf("  DOS Version:       %.2f\n", (float) get_dos_version() / 100.0);
  346. printf("  LANtastic Version: %.2f\n",(float) get_lan_version() / 100.0);
  347. puts("───────────────────────────────────");  
  348. }
  349.  
  350. /* process_options ********************************************************************
  351.  
  352. *****************************************************************************/
  353. int process_options(string)
  354.   char *string;
  355. {
  356.   if (!strcmpi(string,"HELP")) {
  357.     puts("SYSTEM utility for LANtastic -- Copyright 1990 by SoftMagic, Inc.");
  358.     puts("All rights reserved.  LANtastic is a trademark of Artisoft, Inc.\n");
  359.     puts("Usage: SYSTEM <expression> [/OPTIONS]");
  360.     puts("Available options are:");
  361.     puts("/REPORT - display the computer's hardware and software configuration");
  362.     puts("/HELP   - display this documentation");
  363.     exit(0);
  364.   }
  365.   else if (!strcmpi(string,"REPORT")) {
  366.     report();
  367.     exit(0);
  368.   }
  369.   else {
  370.     printf("<%s> isn't a valid command line option.\n",string);
  371.     puts("Type SYSTEM /HELP for a summary of instructions.");
  372.   }
  373. }
  374.  
  375. /* process_file ********************************************************************
  376.  
  377. *****************************************************************************/
  378. process_file(fname,string)
  379.   char *fname,*string;
  380. {
  381.   FILE *file;
  382.   int length;
  383.   
  384.   file = fopen(fname,"rt");
  385.   if (file == NULL) {
  386.     printf("Error: Unable to open input file %s\n",fname);
  387.     exit(-1);
  388.   }
  389.   length = fread(string,1,CMD_LINE_LENGTH,file);
  390.   string[length] = 0;
  391.   strupr(string);
  392.   puts(string);
  393.   fclose(file);  
  394. }
  395.  
  396. /* main  ********************************************************************
  397.  
  398. *****************************************************************************/
  399. int main(argc,argv) 
  400.   int argc;
  401.   char *argv[];
  402. {
  403.   int i,result,curr_item;
  404.   
  405. /* combine command line into a single string */  
  406.   cmdline[0] = 0;
  407.   if (argc >= 2) {
  408.     for (i = 1;i < argc;i++) {
  409.       if (argv[i][0] == '/') {          /* handle options */
  410.         process_options(&argv[i][1]);
  411.         continue;
  412.       }
  413.       else if (argv[i][0] == '@') {     /* command file */
  414.         process_file(&argv[i][1],cmdline);
  415.         continue;
  416.       }
  417.       else {
  418.         strupr(argv[i]);
  419.         strcat(cmdline," ");
  420.         strcat(cmdline,argv[i]);
  421.       }  
  422.     }  
  423.   }
  424.   else {
  425.     process_options("HELP");
  426.   }
  427.  
  428. /* parse command line using the ol' APL scanning technique --
  429.    scan from right to left, using no precedence and ignoring parenthesis */
  430.    
  431.   get_token();
  432.   
  433.   while (strlen(gl_token)) {
  434.     result = find(gl_token);
  435.     if (keywords[result].type == RPAR) evaluate();
  436.     else if (keywords[result].type != LPAR) {
  437.       curr_item = substitute(gl_token,result);
  438.       push(curr_item);
  439.     }
  440.     get_token();
  441.   }
  442.   if (stack_items() >= 3) evaluate();
  443.  
  444. /* retrieve final result */
  445.   curr_item = pop();
  446.   return(!curr_item);
  447. }  
  448.      
  449.    
  450. 
  451.